package com.sinosoft.vaccinetoai.common.converter;

import com.sinosoft.vaccinetoai.common.sse.SSEConstants;
import com.sinosoft.vaccinetoai.exception.BusinessException;
import com.sinosoft.vaccinetoai.common.ApiResult;
import com.sinosoft.vaccinetoai.exception.ExceptionEnums;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.DispatcherType;
import javax.servlet.http.HttpServletRequest;

/**
 * ResponseBody处理（在converter之前调用）
 * @author xzh
 * @date 2022-10-24 14:10
 * @since 5.0.0
 */
@ControllerAdvice(basePackages = { "com.sinosoft.vaccinetoai", "org.springframework.boot.autoconfigure.web.servlet.error"})
public class CustomResponseBodyAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return !ApiResult.class.equals(returnType.getParameterType()) && !returnType.getDeclaringClass().getPackage().getName().startsWith("com.sinosoft.vaccinetoai.business.h3cai");
    }


    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        //覆盖状态码
        response.setStatusCode(HttpStatus.OK);

        HttpServletRequest httpServletRequest = ((ServletServerHttpRequest) request).getServletRequest();

        // ❗判断是否为 SSE 请求（关键逻辑）
        StringBuffer requestURL = httpServletRequest.getRequestURL();
        //SSE 流式不在统一HTTP处理
        if (SSEConstants.HTTP_RESPONSE_NO_FILTER.contains(requestURL.toString())) {
            return body; // 不进行封装，直接返回流
        }

        /**
         * 异常处理
         * 判断DispatcherType是否为ERROR
         */
        if(DispatcherType.ERROR.equals(httpServletRequest.getDispatcherType())) {
            Object errorAttribute = httpServletRequest.getAttribute("org.springframework.boot.web.servlet.error.DefaultErrorAttributes.ERROR");
            if(errorAttribute instanceof BusinessException) {
                return ApiResult.ofBusinessException((BusinessException) errorAttribute);
            }else {
                return ApiResult.ofExceptionEnums(ExceptionEnums.ERROR);
            }
        }

        /**
         * 封装返参
         */
        return ApiResult.success(body);
    }

}
